package com.fw.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

public class UTextFile {
    private static final long MemSize = (long) 256 * (long) 1024;// (long) 4194304;
    private boolean streamMode = false;
    private File oriFile = null;
    private String oriEncode = null;
    private StringBuffer buff = null;
    private InputStream is = null;
    private InputStreamReader isr = null;
    private BufferedReader br = null;

    private void processConstructor(InputStream is, String encode, boolean streamMode) throws UnsupportedEncodingException {
	this.streamMode = streamMode;
	if (is != null) {
	    try {
		this.oriEncode = encode;
		if (Charset.isSupported(this.oriEncode)) {
		    this.is = is;
		    this.isr = new InputStreamReader(is, this.oriEncode);
		    if (this.streamMode == false) {
			BufferedReader br = new BufferedReader(this.isr);
			this.buff = new StringBuffer();
			String buffLine = "";
			while ((buffLine = br.readLine()) != null) {
			    buff.append(buffLine + "\n");
			}
		    }
		} else {
		    throw new UnsupportedEncodingException("Charset encoding [" + this.oriEncode + "] is not supported");
		}
	    } catch (Exception err) {
		err.printStackTrace();
	    }
	} else {
	    System.err.println("UTextFile : UTextFile - InputStream is null");
	}
    }

    public UTextFile(File textFile, String encode) throws UnsupportedEncodingException {
	if (textFile != null) {
	    try {
		this.oriFile = textFile;
		this.oriEncode = encode;
		InputStream is = new FileInputStream(textFile);
		if (textFile.length() > UTextFile.MemSize) {
		    this.processConstructor(is, encode, true);
		} else {
		    this.processConstructor(is, encode, false);
		}
	    } catch (Exception err) {
		err.printStackTrace();
	    }
	} else {
	    System.err.println("UTextFile : UTextFile - Text File is null");
	}
    }

    public UTextFile(File textFile) throws UnsupportedEncodingException {
	this(textFile, "UTF-8");
    }

    public UTextFile(InputStream is, String encode) throws UnsupportedEncodingException {
	if (is != null) {
	    this.processConstructor(is, encode, true);
	} else {
	    System.err.println("UTextFile : UTextFile - InputStream is null");
	}
    }

    public UTextFile(InputStream is) throws UnsupportedEncodingException {
	if (is != null) {
	    this.processConstructor(is, "UTF-8", true);
	} else {
	    System.err.println("UTextFile : UTextFile - InputStream is null");
	}
    }

    public boolean writeFile(File textFile, String encode) throws UnsupportedEncodingException {
	if (textFile != null) {
	    FileOutputStream fos = null;
	    OutputStreamWriter osw = null;
	    try {
		if (Charset.isSupported(encode)) {
		    fos = new FileOutputStream(textFile);
		    osw = new OutputStreamWriter(fos, encode);
		    if (this.streamMode) {
			BufferedReader br = new BufferedReader(this.isr);
			this.buff = new StringBuffer();
			String buffLine = "";
			while ((buffLine = br.readLine()) != null) {
			    osw.write(buffLine + "\n");
			}
		    } else {
			osw.write(this.buff.toString());
		    }
		    return true;
		} else {
		    throw new UnsupportedEncodingException("Charset encoding [" + encode + "] is not supported");
		}
	    } catch (Exception err) {
		err.printStackTrace();
		return false;
	    } finally {
		try {
		    osw.flush();
		    osw.close();
		} catch (IOException e1) {
		    e1.printStackTrace();
		}
		try {
		    fos.flush();
		    fos.close();
		} catch (IOException e) {
		    e.printStackTrace();
		}
	    }
	} else {
	    System.err.println("UTextFile : writeFile - Unable to write to null file");
	    return false;
	}
    }

    public boolean writeFile(File textFile) throws UnsupportedEncodingException {
	return this.writeFile(textFile, this.oriEncode);
    }

    public boolean saveFile(String encode) throws UnsupportedEncodingException {
	return this.writeFile(this.oriFile, encode);
    }

    public boolean saveFile() throws UnsupportedEncodingException {
	return this.writeFile(this.oriFile, this.oriEncode);
    }

    public String getTextString() {
	if (this.streamMode) {
	    BufferedReader br = new BufferedReader(this.isr);
	    this.buff = new StringBuffer();
	    String buffLine = "";
	    try {
		while ((buffLine = br.readLine()) != null && (this.buff.toString().getBytes().length <= UTextFile.MemSize)) {
		    this.buff.append(buffLine + "\n");
		}
		return this.buff.toString();
	    } catch (Exception err) {
		err.printStackTrace();
		return null;
	    } finally {
		try {
		    isr = new InputStreamReader(this.is, this.oriEncode);
		} catch (Exception err) {
		    err.printStackTrace();
		}
	    }
	} else {
	    return this.buff.toString();
	}
    }

    public boolean resetStream() {
	if (this.streamMode && this.br != null) {
	    try {
		this.br.reset();
		return true;
	    } catch (Exception err) {
		err.printStackTrace();
		return false;
	    }
	} else {
	    return false;
	}
    }

    public String readln() {
	if (this.streamMode) {
	    if (this.br == null) {
		this.br = new BufferedReader(this.isr);
	    }
	} else {
	    if (this.br == null) {
		this.br = new BufferedReader(new StringReader(this.buff.toString()));
	    }
	}
	String buffLine = "";
	try {
	    if ((buffLine = this.br.readLine()) != null) {
		return buffLine;
	    } else {
		this.br = null;
		return null;
	    }
	} catch (Exception err) {
	    err.printStackTrace();
	    return null;
	}
    }
}
